import Layer from '../core/Layer';
import DashLine from '../base/DashLine';
import Line from '../base/Line';
import MultiLine from '../base/MultiLine';
import Circle from '../base/Circle';
import Point from '../core/Point';
import Text from '../base/Text';
import Color from '../core/Color';
import Event from '../event/Event';
import OChart from '../core/OChart';
function yLabelDefaultCallback(value) {
    return {
        text: `${value}`,
        size: 20
    };
}
export default class extends Layer {
    constructor(canvas, option) {
        super(canvas);
        this.width = option.width;
        this.height = option.height;
        this.lines = option.data || [];
        this.index = option.data[0] ? option.data[0].length : 0;
        this.yLabelCount = option.yLabelCount || 5;
        this.yLabelCallback = option.yLabelCallback || yLabelDefaultCallback;
        this.color = option.color || '#333333';
        this.lineColors = option.lineColors || [];
        this.touchCallback = option.touchCallback;
        this.touchEndCallback = option.touchEndCallback;
    }

    make() {
        this.childs.splice(0, this.childs.length);
        this.clearEventListener();
        if (this.lines.length === 0 || this.lines[0].length === 0) {
            return;
        }

        let max = this.lines[0][0].value;
        let min = this.lines[0][0].value;
        for (let i = 0; i < this.lines.length; i++) {
            for (let j = 0; j < this.lines[0].length; j++) {
                if (this.lines[i][j].value > max) {
                    max = this.lines[i][j].value;
                }
                if (this.lines[i][j].value < min) {
                    min = this.lines[i][j].value;
                }
            }
        }

        if (max === min) {
            max += max / 4;
            min -= min / 4;
        }

        let ytxt = this.yLabelCallback(max);
        let yTxtLen = ytxt.text.length * ytxt.size * 0.618;
        this.yTxtLen = yTxtLen;
        this.xStep = (this.width - yTxtLen) / (this.lines[0].length + 1);
        this.yStep = this.height / (max - min);
        for (let i = 0; i < this.yLabelCount; i++) {
            let yPosition = Math.round(this.position.y + (i + 1) * (max - min) / this.yLabelCount * this.yStep);
            let dashLine = new DashLine(this.canvas, {
                from: new Point(this.position.x + yTxtLen, yPosition),
                to: new Point(this.position.x + this.width, yPosition)
            });
            dashLine.setColor(new Color(this.color));
            let txtInfo = this.yLabelCallback(min + (i + 1) * (max - min) / this.yLabelCount);
            let txt = new Text(this.canvas, {
                text: txtInfo.text,
                size: txtInfo.size,
                font: 'Aprial',
                color: new Color(this.color)
            });
            txt.setPosition(this.position.x, this.position.y + (i + 1) * (max - min) / this.yLabelCount * this.yStep - txtInfo.size / 2);
            this.addChild(dashLine, txt);
        }
        let line = new Line(this.canvas, {
            from: new Point(this.position.x + yTxtLen, this.position.y),
            to: new Point(this.position.x + this.width, this.position.y)
        });
        line.setColor(new Color(this.color));
        let txtInfo = this.yLabelCallback(min);
        let txt = new Text(this.canvas, {
            text: txtInfo.text,
            size: txtInfo.size,
            font: 'Aprial',
            color: new Color(this.color)
        });
        txt.setPosition(this.position.x, this.position.y);
        this.addChild(line, txt);
        for (let i = 0; i < this.lines.length; i++) {
            let points = [];
            for (let j = 0; j < this.index; j++) {
                let point = new Point(this.position.x + (j * this.xStep) + yTxtLen, this.position.y + (this.lines[i][j].value - min) * this.yStep);
                points.push(point);
                let circle = new Circle(this.canvas, 4);
                circle.setColor(new Color(this.lineColors[i]));
                circle.setPosition(point);
                this.addChild(circle);
            }
            let multiLine = new MultiLine(this.canvas, points);
            multiLine.setLineWidth(2);
            multiLine.setColor(new Color(this.lineColors[i]));
            this.addChild(multiLine);
        }
        this.addEventListener(
            OChart.version === OChart.VERSION.MOBILE
                ? Event.EVENT_TOUCH_START
                : Event.EVENT_CLICK
            , (e) => {
            let { eventPoint } = e;
            const box = this.canvas.canvas.getBoundingClientRect();
            const index = Math.round((eventPoint.x - yTxtLen) / this.xStep);
            const eventX = index * this.xStep * box.width / this.canvas.width + box.left;
            const eventY = eventPoint.y * box.height / this.canvas.height + box.top;
            let info = [];
            this.touchLine = new Line(this.canvas, {
               from: new Point(this.position.x + (index * this.xStep) + yTxtLen, this.position.y + this.height),
               to: new Point(this.position.x + (index) * this.xStep + yTxtLen, this.position.y)
            });
            this.touchLine.setColor(new Color(this.color));
            this.addChild(this.touchLine);
            this.canvas.paint();
            for (let i = 0; i < this.lines.length; i++) {
                info.push(this.lines[i][index]);
            }
            this.touchCallback && this.touchCallback(info, { x: eventX, y: eventY });
        });
        this.addEventListener(
            OChart.version === OChart.VERSION.MOBILE
                ? Event.EVENT_TOUCH_END
                : Event.EVENT_MOUSE_UP
            , (e) => {
                if (this.touchLine) {
                    let index = this.childs.indexOf(this.touchLine);
                    if (index >= 0) {
                        this.childs.splice(index, 1);
                        this.canvas.paint();
                    }
                }
                this.touchEndCallback && this.touchEndCallback(e);
            }
        )

    }
    /**
     * 点击检测
     * @param point
     * @returns {boolean}
     */
    containsPoint(point) {
        return point.x <= this.position.x + this.width
            && point.x >= this.position.x
            && point.y >= this.position.y
            && point.y <= this.position.y + this.height;
    }

}
